home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / pinfocom_3_0.lha / Source / interp.c < prev    next >
C/C++ Source or Header  |  1992-10-22  |  8KB  |  281 lines

  1. /* interp.c
  2.  *
  3.  *  ``pinfocom'' -- a portable Infocom Inc. data file interpreter.
  4.  *  Copyright (C) 1987-1992  InfoTaskForce
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; see the file COPYING.  If not, write to the
  18.  *  Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. /*
  22.  * $Header: RCS/interp.c,v 3.0 1992/10/21 16:56:19 pds Stab $
  23.  */
  24.  
  25. #include <stdio.h>
  26. #ifndef NO_SIGNALS
  27. #include <signal.h>
  28. #endif
  29.  
  30. #include "infocom.h"
  31.  
  32.  
  33. static void
  34. execute A3(word, opcode, word, num, word *, param)
  35. {
  36.     switch (opcode)
  37.     {
  38.         case 0x01 : compare(num, param);
  39.                     break;
  40.         case 0x02 : LTE(param[0], param[1]);
  41.                     break;
  42.         case 0x03 : GTE(param[0], param[1]);
  43.                     break;
  44.         case 0x04 : dec_chk(param[0], param[1]);
  45.                     break;
  46.         case 0x05 : inc_chk(param[0], param[1]);
  47.                     break;
  48.         case 0x06 : check_loc(param[0], param[1]);
  49.                     break;
  50.         case 0x07 : bit(param[0], param[1]);
  51.                     break;
  52.         case 0x08 : or(param[0], param[1]);
  53.                     break;
  54.         case 0x09 : and(param[0], param[1]);
  55.                     break;
  56.         case 0x0a : test_attr(param[0], param[1]);
  57.                     break;
  58.         case 0x0b : set_attr(param[0], param[1]);
  59.                     break;
  60.         case 0x0c : clr_attr(param[0], param[1]);
  61.                     break;
  62.         case 0x0d : put_var(param[0], param[1]);
  63.                     break;
  64.         case 0x0e : transfer(param[0], param[1]);
  65.                     break;
  66.         case 0x0f : load_word_array(param[0], param[1]);
  67.                     break;
  68.         case 0x10 : load_byte_array(param[0], param[1]);
  69.                     break;
  70.         case 0x11 : get_prop(param[0], param[1]);
  71.                     break;
  72.         case 0x12 : get_prop_addr(param[0], param[1]);
  73.                     break;
  74.         case 0x13 : next_prop(param[0], param[1]);
  75.                     break;
  76.         case 0x14 : plus(param[0], param[1]);
  77.                     break;
  78.         case 0x15 : minus(param[0], param[1]);
  79.                     break;
  80.         case 0x16 : multiply(param[0], param[1]);
  81.                     break;
  82.         case 0x17 : divide(param[0], param[1]);
  83.                     break;
  84.         case 0x18 : mod(param[0], param[1]);
  85.                     break;
  86.         /*
  87.          * Missing opcode
  88.          */
  89.         case 0x20 : gosub(num, param);
  90.                     break;
  91.         case 0x21 : save_word_array(param[0], param[1], param[2]);
  92.                     break;
  93.         case 0x22 : save_byte_array(param[0], param[1], param[2]);
  94.                     break;
  95.         case 0x23 : put_prop(param[0], param[1], param[2]);
  96.                     break;
  97.         case 0x24 : input(param[0], param[1]);
  98.                     break;
  99.         case 0x25 : print_char(param[0]);
  100.                     break;
  101.         case 0x26 : print_num(param[0]);
  102.                     break;
  103.         case 0x27 : pi_random(param[0]);
  104.                     break;
  105.         case 0x28 : push(param[0]);
  106.                     break;
  107.         case 0x29 : pop(param[0]);
  108.                     break;
  109.         case 0x2a : scr_window(param[0]);
  110.                     break;
  111.         case 0x2b : scr_set_win(param[0]);
  112.                     break;
  113.         /*
  114.          * Missing opcodes
  115.          */
  116.         case 0x33 : break;                  /* SET_PRINT (?) */
  117.         case 0x34 : break;                  /* #RECORD_MODE (?) */
  118.         case 0x35 : scr_putsound(param[0], param[1], param[2], num);
  119.                     break;
  120.  
  121.         default: error("execute: Invalid Z-code instruction: $%02x", opcode);
  122.     }
  123. }
  124.  
  125. static void
  126. oper1 A1(word, opcode)
  127. {
  128.     word    param1;
  129.  
  130.     param1 = load((opcode >> 4) & 0x03);
  131.     switch (opcode & 0x0F)
  132.     {
  133.         case 0x00 : cp_zero(param1);
  134.                     break;
  135.         case 0x01 : get_link(param1);
  136.                     break;
  137.         case 0x02 : get_holds(param1);
  138.                     break;
  139.         case 0x03 : get_loc(param1);
  140.                     break;
  141.         case 0x04 : get_prop_len(param1);
  142.                     break;
  143.         case 0x05 : inc_var(param1);
  144.                     break;
  145.         case 0x06 : dec_var(param1);
  146.                     break;
  147.         case 0x07 : print1(param1);
  148.                     break;
  149.         /*
  150.          * Opcode 0x08: unknown
  151.          */
  152.         case 0x09 : remove_obj(param1);
  153.                     break;
  154.         case 0x0a : p_obj(param1);
  155.                     break;
  156.         case 0x0b : rtn(param1);
  157.                     break;
  158.         case 0x0c : jump(param1);
  159.                     break;
  160.         case 0x0d : print2(param1);
  161.                     break;
  162.         case 0x0e : get_var(param1);
  163.                     break;
  164.         case 0x0f : not(param1);
  165.                     break;
  166.         default   : error("oper1: Invalid Z-code instruction: $%02x", opcode);
  167.     }
  168. }
  169.  
  170. static void
  171. oper2 A1(word, opcode)
  172. {
  173.     word    param[2];
  174.     int     mode;
  175.  
  176.     mode = 1 + ((opcode & 0x40) != 0);
  177.     param[0] = load(mode);
  178.  
  179.     mode = 1 + ((opcode & 0x20) != 0);
  180.     param[1] = load(mode);
  181.  
  182.     execute((opcode & 0x1F), 2, param);
  183. }
  184.  
  185. static void
  186. oper3 A1(word, opcode)
  187. {
  188.     word    param[4];
  189.     word    *pp;
  190.     word    num_params;
  191.     byte    modes;
  192.     int     addr_mode;
  193.     int     i;
  194.  
  195.     NEXT_BYTE(modes);
  196.     num_params = 0;
  197.  
  198.     for (i=6, pp=param; i >= 0; ++pp, i-=2)
  199.     {
  200.         addr_mode = (modes >> i) & 0x03;
  201.         if (addr_mode == 3)
  202.             break;
  203.  
  204.         ++num_params;
  205.         *pp = load(addr_mode);
  206.     }
  207.  
  208.     for (; i >= 0; ++pp, i-=2)
  209.         *pp = 0;
  210.  
  211.     execute((opcode & 0x3F), num_params, param);
  212. }
  213.  
  214. void
  215. interp()
  216. {
  217.     word            opcode;
  218.  
  219. #ifndef NO_SIGNALS
  220.     signal(SIGINT, askq);
  221. #ifdef SIGQUIT
  222.     signal(SIGQUIT, SIG_IGN);
  223. #endif
  224. #endif
  225.  
  226.     while (gflags.game_state != QUIT_GAME)
  227.     {
  228.         NEXT_BYTE(opcode);
  229.         if (opcode < 0x80)
  230.         {
  231.             oper2(opcode);
  232.             continue;
  233.         }
  234.         if (opcode < 0xb0)
  235.         {
  236.             oper1(opcode);
  237.             continue;
  238.         }
  239.         if (opcode >= 0xc0)
  240.         {
  241.             oper3(opcode);
  242.             continue;
  243.         }
  244.  
  245.         switch (opcode & 0x0F)
  246.         {
  247.             case 0x00 : rtn(1);
  248.                         break;
  249.             case 0x01 : rtn(0);
  250.                         break;
  251.             case 0x02 : wrt();
  252.                         break;
  253.             case 0x03 : writeln();
  254.                         break;
  255.             case 0x04 : null();
  256.                         break;
  257.             case 0x05 : save();
  258.                         break;
  259.             case 0x06 : restore();
  260.                         break;
  261.             case 0x07 : restart();
  262.                         break;
  263.             case 0x08 : rts();
  264.                         break;
  265.             case 0x09 : pop_stack();
  266.                         break;
  267.             case 0x0a : quit();
  268.                         break;
  269.             case 0x0b : new_line();
  270.                         break;
  271.             case 0x0c : set_score();
  272.                         scr_putscore();
  273.                         break;
  274.             case 0x0d : verify();
  275.                         break;
  276.  
  277.             default: error("interp: Invalid Z-code instruction: $%02x",opcode);
  278.         }
  279.     }
  280. }
  281.